package com.umeox.moto.watch.themes.widget.wheel

import java.util.regex.Pattern
import kotlin.math.abs
import kotlin.math.max

/*
*  Copyright 2010 Yuri Kanivets
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
/**
 * Numeric Wheel adapter.
 */
class NumericWheelAdapter : WheelAdapter {
    // Values
    private var minValue: Int

    private var maxValue: Int

    // format
    private var format: String? = null

    private var valueType: Int
    private var stringArray: Array<String>? = null

    fun setMinValue(minValue: Int) {
        this.minValue = minValue
    }

    fun setMaxValue(maxValue: Int) {
        this.maxValue = maxValue
    }

    /**
     * Constructor
     *
     * @param minValue the wheel min value
     * @param maxValue the wheel max value
     * @param format the format string
     */
    /**
     * Constructor
     *
     * @param minValue the wheel min value
     * @param maxValue the wheel max value
     */
    /**
     * Default constructor
     */
    @JvmOverloads
    constructor(minValue: Int = DEFAULT_MIN_VALUE, maxValue: Int = DEFAULT_MAX_VALUE, format: String? = null, type: Int = TYPE_INT) {
        this.minValue = minValue
        this.maxValue = maxValue
        this.format = format
        this.valueType = type
    }

    constructor(minValue: Int, maxValue: Int, type: Int) {
        this.minValue = minValue
        this.maxValue = maxValue
        this.valueType = type
    }

    constructor(minValue: Int, maxValue: Int, type: Int, stringArray: Array<String>) {
        this.minValue = minValue
        this.maxValue = maxValue
        this.format = format
        this.valueType = type
        this.stringArray = stringArray
    }

    override fun getItem(index: Int): String? {
        if (valueType == TYPE_INT) {
            if (index >= 0 && index < itemsCount) {
                val value = minValue + index
                return if (format != null) String.format(format!!, value) else value.toString()
            }
        } else if (valueType == TYPE_FLOAT) {
            val devide = 0.5f
            var weight: String
            val pattern = Pattern.compile("[\\d]+[\\.][0]")

            if (index >= 0 && index < itemsCount) {
                if (index < 16) {
                    weight = (minValue + ((index + 1) * devide)).toString()
                    val matcher = pattern.matcher(weight)
                    if (matcher.matches()) {
                        weight = weight.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0]
                    }
                    return if (format != null) String.format(format!!, weight) else weight
                } else {
                    weight = (10 + (index - 15)).toString()
                    return if (format != null) String.format(format!!, weight) else weight
                }
            }
        } else if (valueType == TYPE_TIME) {
            return if (index <= 9) {
                "0$index"
            } else {
                index.toString()
            }
        } else if (valueType == TYPE_STRING) {
            return stringArray?.get(index)
        }

        return null
    }

    override val itemsCount: Int
        get() = maxValue - minValue + 1

    override val maximumLength: Int
        get() {
            val max = max(abs(maxValue.toDouble()), abs(minValue.toDouble())).toInt()
            var maxLen = max.toString().length
            if (minValue < 0) {
                maxLen++
            }
            return maxLen
        }

    companion object {
        /** The default min value  */
        const val DEFAULT_MAX_VALUE: Int = 9

        /** The default max value  */
        private const val DEFAULT_MIN_VALUE = 0

        const val TYPE_FLOAT: Int = 11
        const val TYPE_TIME: Int = 18
        const val TYPE_STRING:Int = 19
        const val TYPE_INT: Int = 10
    }
}
